package org.apache.rmiloader.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

public class RmiLoaderConfig extends Properties {

	private static final long serialVersionUID = -4574370945105848598L;
	private static String appServerHome;
	private static RmiLoaderConfig inst = null;
	private final String RMI_CONF = "rmiloader.properties";
	
	public static final String CATALINA_BASE = "catalina.base";
	public static final String CATALINA_HOME = "catalina.home";
	public static final String COMMON_LOADER = "common.loader";
	
	public static final String RMI_HOST = "rmi.registry.host";
	public static final String RMI_PORT = "rmi.registry.port";
	public static final String VERSION = "Implementation-Version";
	public static final String BUILD = "Implementation-Build";
	public static final String BUILD_DATE = "Implementation-Date";
	public static final String AUTHOR = "Built-By";
	
	public static void setAppHome(String path) {
		appServerHome = path;
	}
	
	private RmiLoaderConfig() {}

	private void loadProperties() {
		ClassLoader cl = Thread.currentThread().getContextClassLoader();
		java.io.InputStream is = cl.getResourceAsStream(RMI_CONF);
	
		try {
			// Try to load external configuration
			File config = new File(System.getProperty(CATALINA_HOME) + "/conf/rmiloader/" + RMI_CONF);
			if (config.exists()) {
				load(new FileInputStream(config));
			//Else create file following internal config and load it
			} else { 
				File dir = new File(System.getProperty(CATALINA_HOME) + "/conf/rmiloader/");
				if (!dir.exists()) { dir.mkdir(); }
				FileOutputStream fos = new FileOutputStream(config);
				int c;
				while ((c = is.read()) != -1) {
					fos.write(c);
				}
				fos.close();
				load(is);
			}
		} catch (Exception e) { 
			throw new RuntimeException(e); 
		}
	}
	
	private void loadMetainf() {
		File manifestFile = new File(appServerHome, "META-INF/MANIFEST.MF");
		 
		Manifest mf = new Manifest();
		try {
			mf.read(new FileInputStream(manifestFile));
		} catch (Exception e) { throw new RuntimeException(e); }

		Attributes atts = mf.getMainAttributes();

		setProperty(VERSION, atts.getValue(VERSION));
		setProperty(BUILD, atts.getValue(BUILD));
		setProperty(BUILD_DATE, atts.getValue(BUILD_DATE));
		setProperty(AUTHOR, atts.getValue(AUTHOR));
	}
	
	public static synchronized RmiLoaderConfig getInstance()
	{
		if (inst == null) {
			inst = new RmiLoaderConfig();
			inst.loadProperties();
			inst.loadMetainf();
		}
		return inst;
	}
}
